package com.shuqi.download.database;

import java.io.File;
import java.io.RandomAccessFile;
import java.sql.SQLException;
import java.util.List;

import android.content.Context;

import com.j256.ormlite.dao.RuntimeExceptionDao;
import com.j256.ormlite.stmt.DeleteBuilder;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.UpdateBuilder;
import com.j256.ormlite.stmt.Where;
import com.shuqi.application.ShuqiApplication;
import com.shuqi.database.dao.OrmBaseDao;
import com.shuqi.database.dao.impl.BookCataLogDao;
import com.shuqi.database.dao.impl.ShuqiDatabaseHelper;
import com.shuqi.download.util.DownloadStatus;
import com.shuqi.download.util.Util;

/**
 * 文件下载信息数据库操作类
 * @author GaoPeng<gaopeng@ucweb.com>
 *
 */
public class DownloadInfoDao extends OrmBaseDao {
    
	private static DownloadInfoDao instance=null;
	
	private static RuntimeExceptionDao<DownloadInfo, String> downloadInfoDao = ShuqiDatabaseHelper.getHelper(
            ShuqiApplication.getContext()).getRuntimeExceptionDao(DownloadInfo.class);
	
	private DownloadInfoDao(Context context) {
		
	}
	
	public static synchronized DownloadInfoDao getInstance() {
		if(instance==null) {
			instance=new DownloadInfoDao(ShuqiApplication.getContext());
			// 初始化
            // 将所有文件正在下载状态更新为停止下载
            UpdateBuilder<DownloadInfo, String> updateBuidler = downloadInfoDao.updateBuilder();
            try {
                Where<DownloadInfo, String> where = updateBuidler.where();
                where.eq("record_type", 1);
                where.and().eq("download_status", DownloadStatus.STATE_RUN);
                updateBuidler.updateColumnValue("download_status", DownloadStatus.STATE_STOP);
                updateBuidler.update();
                // ** 此处代码需要优化
                where = updateBuidler.where();
                where.eq("record_type", 1);
                where.and().eq("download_status", DownloadStatus.STATE_WAIT);
                updateBuidler.updateColumnValue("download_status", DownloadStatus.STATE_STOP);
                updateBuidler.update();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            // 将所有文件正在解压状态更新为停止解压
            updateBuidler = downloadInfoDao.updateBuilder();
            try {
                Where<DownloadInfo, String> where = updateBuidler.where();
                where.eq("record_type", 1);
                where.and().eq("download_status", DownloadStatus.STATE_UNZIP);
                updateBuidler.updateColumnValue("download_status", DownloadStatus.STATE_UNZIP_STOP);
                updateBuidler.update();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            // 根据线程状态更新文件状态
            
		}
		return instance;
	}
	
	/**
     * 添加记录
     * @param downloadInfo
     */
    public void save(DownloadInfo downloadInfo) {
        downloadInfoDao.create(downloadInfo);
    }
    
    /**
     * 更新记录
     * @param downloadInfo
     */
    public void update(DownloadInfo downloadInfo) {
        // 如果下载成功更新目录数据库（有耦合！）
        if(downloadInfo.getDownloadStatus()==DownloadStatus.STATE_DONE) {
            BookCataLogDao.getInstance().updateAllCatalogToDown(downloadInfo.getBookId(), downloadInfo.getUserId());
        }
        downloadInfoDao.update(downloadInfo);
    }
    
    /**
     * 删除单个文件下载记录
     */
    public void deleteDownloadInfo(String uid,String bid) {
        DeleteBuilder<DownloadInfo, String> deleteBuilder = downloadInfoDao.deleteBuilder();
        try {
            Where<DownloadInfo, String> where = deleteBuilder.where();
            where.eq("user_id", uid);
            where.and().eq("book_id", bid);
            deleteBuilder.delete();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 获取所有记录
     * @return
     */
    public List<DownloadInfo> getAll() {
        QueryBuilder<DownloadInfo, String> queryBuilder = downloadInfoDao.queryBuilder();
        try {
            queryBuilder.orderBy("id", true);
            List<DownloadInfo> downloadInfoList = queryBuilder.query();
            return downloadInfoList;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 获取单个文件下载记录
     * @param uid
     * @param bid
     * @return
     */
    public DownloadInfo getDownloadInfo(String uid,String bid) {
        QueryBuilder<DownloadInfo, String> queryBuilder = downloadInfoDao.queryBuilder();
        try {
            Where<DownloadInfo, String> where = queryBuilder.where();
            where.eq("user_id", uid);
            where.and().eq("book_id", bid);
            where.and().eq("record_type", 1);
            queryBuilder.orderBy("id", false);
            List<DownloadInfo> downloadInfoList = queryBuilder.query();
            if(downloadInfoList!=null&&downloadInfoList.size()>0) {
                return downloadInfoList.get(0);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 获取所有文件下载记录
     * @param uid
     * @param bid
     * @return
     */
    public List<DownloadInfo> getAllDownloadInfo() {
        QueryBuilder<DownloadInfo, String> queryBuilder = downloadInfoDao.queryBuilder();
        try {
            Where<DownloadInfo, String> where = queryBuilder.where();
            where.eq("record_type", 1);
            queryBuilder.orderBy("id", true);
            List<DownloadInfo> downloadInfoList = queryBuilder.query();
            return downloadInfoList;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 获取单个文件所有线程记录
     * 
     * @return
     */
    public List<DownloadInfo> getAllDownloadThreadInfo(String uid,String bid) {
        QueryBuilder<DownloadInfo, String> queryBuilder = downloadInfoDao.queryBuilder();
        try {
            Where<DownloadInfo, String> where = queryBuilder.where();
            where.eq("user_id", uid);
            where.and().eq("book_id", bid);
            where.and().eq("record_type", 0);
            queryBuilder.orderBy("id", true);
            List<DownloadInfo> downloadInfoList = queryBuilder.query();
            return downloadInfoList;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 获取下载线程记录
     */
    public List<DownloadInfo> getAllDownloadThreadInfo(String uid,String bid,String fileUrl,int fileLength,int threadCount,String filePath) {
        
        try {
            // 是否重新下载
            boolean isRenew=false;
            
            DownloadInfo downloadInfo=DownloadInfoDao.getInstance().getDownloadInfo(uid, bid);
            if(downloadInfo==null) {
                Util.log("数据库没有记录");
                isRenew=true;
            } else if(downloadInfo.getFileUrl()==null||!downloadInfo.getFileUrl().equalsIgnoreCase(fileUrl)){
                Util.log("下载文件URL有变化（"+fileUrl+","+downloadInfo.getFileUrl()+"）");
                isRenew=true;
            } else if(downloadInfo.getPosEnd()!=fileLength) {
                Util.log("下载文件大小有变化（"+fileLength+","+downloadInfo.getPosEnd()+"）");
                isRenew=true;
            } else {
                // 原记录是否损坏
                QueryBuilder<DownloadInfo, String> queryBuilder = downloadInfoDao.queryBuilder();
                try {
                    Where<DownloadInfo, String> where = queryBuilder.where();
                    where.eq("user_id", uid);
                    where.and().eq("book_id", bid);
                    where.and().eq("record_type", 0);
                    queryBuilder.orderBy("pos_end", true);
                    List<DownloadInfo> downloadInfoList = queryBuilder.query();
                    if(downloadInfoList!=null) {
                        int threadCount2=downloadInfoList.size();
                        int[][] arr=Util.getRegion(downloadInfo.getPosEnd(),threadCount2);
                        int i=0;
                        for(DownloadInfo downloadInfo2:downloadInfoList) {
                            if(downloadInfo2.getPosStart()!=arr[i][0]||downloadInfo2.getPosEnd()!=arr[i][1]) {
                                isRenew=true;
                                Util.log("数据库原记录有损坏");
                                break;
                            }
                            i++;
                        }
                    } else {
                        isRenew=true;
                    }
                    // 判断下载缓存文件是否有损坏
                    if(Util.isFileDamage(filePath,fileLength)) {
                        isRenew=true;
                        Util.log("下载缓存文件有损坏");
                    }
                } catch (SQLException e) {
                    isRenew=true;
                    e.printStackTrace();
                }
            }
            
            if(isRenew) {// 重新下载
                Util.log("重新创建下载");
                // 删除所有记录
                DeleteBuilder<DownloadInfo, String> deleteBuilder = downloadInfoDao.deleteBuilder();
                try {
                    Where<DownloadInfo, String> where = deleteBuilder.where();
                    where.eq("user_id", uid);
                    where.and().eq("book_id", bid);
                    deleteBuilder.delete();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                // 新建记录
                int[][] arr=Util.getRegion(fileLength,threadCount);
                DownloadInfo downloadInfo2=new DownloadInfo();
                downloadInfo2.setUserId(uid);
                downloadInfo2.setBookId(bid);
                downloadInfo2.setFileUrl(fileUrl);
                downloadInfo2.setPosEnd(fileLength);
                downloadInfo2.setRecordType(1);
                save(downloadInfo2);
                int i=0;
                for(;i<arr.length;i++) {
                    downloadInfo2=new DownloadInfo();
                    downloadInfo2.setUserId(uid);
                    downloadInfo2.setBookId(bid);
                    downloadInfo2.setFileUrl(fileUrl);
                    downloadInfo2.setPosStart(arr[i][0]);
                    downloadInfo2.setPosEnd(arr[i][1]);
                    save(downloadInfo2);
                }
                // 删除损坏文件
                File file=new File(filePath);
                if(file!=null&&file.exists()) {
                    file.delete();
                }
                // 创建缓存文件
                File destFolder = new File(Util.getFileFolder(filePath));
                if(!destFolder.exists()) {
                    destFolder.mkdirs();
                }
                RandomAccessFile accessFile = new RandomAccessFile(new File(filePath), "rwd");
                accessFile.setLength(fileLength);
                accessFile.close();
            }
            
            // 读取文件下载线程记录
            QueryBuilder<DownloadInfo, String> queryBuilder = downloadInfoDao.queryBuilder();
            try {
                Util.log("读取下载线程记录");
                Where<DownloadInfo, String> where = queryBuilder.where();
                where.eq("user_id", uid);
                where.and().eq("book_id", bid);
                where.and().eq("record_type", 0);
                queryBuilder.orderBy("pos_end", true);
                List<DownloadInfo> downloadInfoList = queryBuilder.query();
                int downLength=0;
                for(DownloadInfo downloadInfo2:downloadInfoList) {
                    Util.log(downloadInfo2.toString());
                    downLength+=downloadInfo2.getDownLength();
                }
                // 根据线程状态更新文件状态
                if(downloadInfo!=null) {
                    downloadInfo.setDownLength(downLength);
                    float percent=Util.getPercent(downLength, downloadInfo.getPosEnd());
                    if((downloadInfo.getDownloadStatus()!=DownloadStatus.STATE_DONE)&&percent==100) {
                        percent=99.99f;
                    }
                    downloadInfo.setDownloadPercent(percent);
                    update(downloadInfo);
                }
                return downloadInfoList;
            } catch (SQLException e) {
                isRenew=true;
                e.printStackTrace();
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
        
        return null;
    }
    
    /**
     * 清理当前实体（否则程序退出可能还alive）
     */
    public void clear() {
        instance=null;
    }
}
